/*==========================================================================*/
/* System Setup                                                             */
/*==========================================================================*/
#include "stdio_s.h"
#include "system.h"

/*==========================================================================*/
/* Setup STDIN and STDOUT                                                   */
/*==========================================================================*/

/*
// Call when write to stdout
void StdoutPutc (char aCh)
{
    os_disp_putc (aCh);
}

// Call when read from stdin
int StdinGetc (void)
{
    int ch;

    do
    {
      ch = os_kbd_getkey ();
      os_sleep ();
    } while (ch == 0);

    return ch;
}

FILE gStdout =
{
    ._IO_buf_base = (unsigned char*)&StdoutPutc
};

FILE gStdin =
{
    ._IO_buf_base = (unsigned char*)&StdinGetc
};

FILE *stdout = &gStdout;
FILE *stdin = &gStdin;
*/

// PC0711
/*
int _write_a(int handle, const unsigned char * buffer, int size)
{
  int nChars = 0;

  if (buffer == 0)
  {
     // This means that we should flush internal buffers.  Since we
     // don't we just return.  (Remember, "handle" == -1 means that all
     // handles should be flushed.)
    return 0;
  }

  for (; size != 0; --size)
  {
    os_disp_putc(*buffer++);
    ++nChars;
  }

  return nChars;
}
*/


/*==========================================================================*/
/* Reset                                                                    */
/* Call after leave main ()                                                 */
/*==========================================================================*/
void PowerOff (void)
{
//PC0711    disable_interrupt ();   /* Fast reset */
//    os_sys_off ();
  os_disp_putc(0x0c);   // flush display
	os_disp_puts ("Pls Power Off");
	while (1) {
		os_sleep();
	}
}
/*==========================================================================*/
/* Segment Initialization on power up                                       */
/* Call before enter main()                                                 */
/*==========================================================================*/

// given by linker script      
extern unsigned long _start_of_data;  // void* pointer
extern unsigned long _end_of_data;
extern unsigned long _end_of_sram;
extern unsigned long _start_of_bss;
extern unsigned long _end_of_bss;
extern unsigned long _end_of_app;

void SegmentInit (void)
{
    unsigned long *src;
    unsigned long *dest;
    unsigned long *end_addr;

// PC0802 for debug
/*
os_disp_putc(0x0c);   // flush display
printf("s_data=%X\n", (unsigned long)&_start_of_data);
printf("e_data=%X\n", (unsigned long)&_end_of_data);
printf("e_sram=%X\n", (unsigned long)&_end_of_sram);
printf("s_bss=%X\n", (unsigned long)&_start_of_bss);
printf("e_bss=%X\n", (unsigned long)&_end_of_bss);
printf("e_app=%X\n", (unsigned long)&_end_of_app);
while (os_kbd_getkey () == 0) os_sleep();
*/
    //------------------------------
    // Check data area size         
    //------------------------------
    if ((unsigned long)&_end_of_bss > (unsigned long)&_end_of_sram)
    {
        os_disp_puts ("\f""Data oversized.");
        while (os_kbd_getkey () == 0)
            os_sleep ();
        PowerOff ();
    }

    //------------------------------
    // Copy preset data             
    //------------------------------
    src = &_end_of_app;
    dest = &_start_of_data;
    end_addr = &_end_of_data;

    while (dest < end_addr)
    {
        *dest = *src;
        src ++;
        dest ++;
    }

    //------------------------------
    // Clear uninitialized data     
    //------------------------------
    dest = &_start_of_bss;
    end_addr = &_end_of_bss;

    while (dest < end_addr)
    {
        *dest = 0;
        dest ++;
    }
}


